package com.contact_book.operations;

import com.contact_book.entity.Address;
import com.contact_book.entity.Contact;
import com.contact_book.exception.ContactNotFoundException;
import com.contact_book.exception.FailedToHandleFileException;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.util.logging.FileHandler;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class ContactBookManager {

    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            File logFile;
            do {
                System.out.print(
                        "\nPoint the directory with the name of the existing .log file, "
                        + "or file is needed to be created and hit Enter:\n> ");

                logFile = checkFile(reader.readLine(), ".log");
            } while (logFile == null);
            setLogging(logFile);

            File fileForContacts;
            do {
                System.out.print(
                        "\nPoint the directory with the name of the existing .csv file, "
                        + "or file is needed to be created and hit Enter:\n> ");
                fileForContacts = checkFile(reader.readLine(), ".csv");
            } while (fileForContacts == null);

            ContactManager contactManager = new ContactManagerImpl(fileForContacts);

            System.out.println("\nTo see the menu type " + SHOW_MENU + " and hit Enter.");

            while (true) {
                String command = reader.readLine();
                if (SHOW_MENU.equalsIgnoreCase(command)) {
                    showMenu();
                } else if (ADD_CONTACT_COMMAND.equalsIgnoreCase(command)) {
                    contactManager.addContact(createContact(reader));
                    System.out.println("\nThe contact was added successfully.\n");
                } else if (SHOW_ALL_CONTACTS_COMMAND.equalsIgnoreCase(command)) {
                    contactManager.showAllContacts();
                } else if (FIND_CONTACT_COMMAND.equalsIgnoreCase(command)) {
                    System.out.print("\nEnter the name of the contact you want to find and hit Enter:\n> ");
                    try {
                        contactManager.findContact(reader.readLine());
                    } catch (ContactNotFoundException cnfe) {
                        System.out.println("\nThe contact was not found. To repeat an attempt type "
                                + FIND_CONTACT_COMMAND + " and hit Enter.\n");
                    }
                } else if (DELETE_CONTACT_COMMAND.equalsIgnoreCase(command)) {
                    System.out.print("\nEnter the name of the contact you want to delete and hit Enter:\n> ");
                    try {
                        contactManager.deleteContact(reader.readLine());
                        System.out.println("\nThe contact was deleted successfully.\n");
                    } catch (ContactNotFoundException cnfe) {
                        System.out.println("\nThe contact was not found. To repeat an attempt type "
                                + DELETE_CONTACT_COMMAND + " and hit Enter.\n");
                    }
                } else if (EXIT_COMMAND.equalsIgnoreCase(command)) {
                    break;
                } else {
                    System.out.println("\nInvalid command. Type " + SHOW_MENU
                            + " to see the accessible commands.\n");
                    continue;
                }
            }
        } catch (FailedToHandleFileException | IOException ex) {
            System.out.println(
                    "\nThere are some problems with the file handling occured. "
                    + "To repeat an attempt launch the application again. "
                    + "For more details see the log report.\n");
            LOGGER.info("some stufffffff");
            System.exit(0);
        }
    }

    private static void setLogging(File file)
            throws FailedToHandleFileException {
        try (InputStream logConfig =
                ContactBookManager.class.getClassLoader().getResourceAsStream(
                "com/contact_book/properties/logging.properties")) {

            LogManager.getLogManager().readConfiguration(logConfig);
            FileHandler handler = new FileHandler(file.getName());
            LOGGER.addHandler(handler);
        } catch (IOException ioc) {
            throw new FailedToHandleFileException(
                    "Failed to create or read the log file.", ioc);
        }
    }

    private static File checkFile(String fileName, String extension)
            throws IOException {
        File file = null;
        File fileToCheck = new File(fileName);
        if (fileToCheck.getName().endsWith(extension)) {
            if (fileToCheck.exists()) {
                file = fileToCheck;
            } else {
                System.out.println(
                        fileToCheck.getAbsolutePath()
                        + " does not exist. The new file will be created.");
                System.out.println(fileName);

                if (Paths.get(fileName).getParent().toFile().exists()) {
                    fileToCheck.createNewFile();
                    file = fileToCheck;
                } else {
                    System.out.println(
                            Paths.get(fileName).getParent().toString()
                            + " - invalid directory.");
                }
            }
        } else {
            System.out.println(
                    fileToCheck.getName() + " - an invalid log file name. Point "
                    + extension + "  file name.");
        }
        return file;
    }

    private static void showMenu() {
        System.out.println("\nTo add a contact type " + ADD_CONTACT_COMMAND + " and hit Enter.");
        System.out.println("To see all contacts type " + SHOW_ALL_CONTACTS_COMMAND + " and hit Enter.");
        System.out.println("To find a contact by name type " + FIND_CONTACT_COMMAND + " and hit Enter.");
        System.out.println("To delete a contact type " + DELETE_CONTACT_COMMAND + " and hit Enter.");
        System.out.println("To quit type " + EXIT_COMMAND + " and hit Enter.\n");
    }

    private static Contact createContact(BufferedReader reader)
            throws IOException {
        Contact contact = new Contact();
        do {
            System.out.print("\nName:\n> ");
            contact.setName(reader.readLine());
        } while (contact.getName() == null
                || contact.getName().trim().isEmpty());

        do {
            System.out.print("\nEmail:\n> ");
            contact.setEmail(reader.readLine());
        } while (contact.getEmail() == null
                || contact.getEmail().trim().isEmpty());

        do {
            System.out.print("\nPhone number:\n> ");
            contact.setPhoneNumber(reader.readLine());
        } while (contact.getPhoneNumber() == null
                || contact.getPhoneNumber().trim().isEmpty());

        contact.setAddress(new Address());
        do {
            System.out.print("\nCity:\n> ");
            contact.getAddress().setCity(reader.readLine());
        } while (contact.getAddress().getCity() == null
                || contact.getAddress().getCity().trim().isEmpty());

        do {
            System.out.print("\nStreet:\n> ");
            contact.getAddress().setStreet(reader.readLine());
        } while (contact.getAddress().getStreet() == null
                || contact.getAddress().getStreet().trim().isEmpty());

        do {
            System.out.print("\nHouse number:\n> ");
            contact.getAddress().setHouseNumber(reader.readLine());
        } while (contact.getAddress().getHouseNumber() == null
                || contact.getAddress().getHouseNumber().trim().isEmpty());

        do {
            System.out.print("\nOffice number:\n> ");
            contact.getAddress().setOfficeNumber(reader.readLine());
        } while (contact.getAddress().getOfficeNumber() == null
                || contact.getAddress().getOfficeNumber().trim().isEmpty());
        return contact;
    }
    private static final String ADD_CONTACT_COMMAND = "ADD";
    private static final String SHOW_ALL_CONTACTS_COMMAND = "SHOW";
    private static final String FIND_CONTACT_COMMAND = "FIND";
    private static final String DELETE_CONTACT_COMMAND = "DELETE";
    private static final String SHOW_MENU = "MENU";
    private static final String EXIT_COMMAND = "EXIT";
    private static final Logger LOGGER = Logger.getLogger(ContactBookManager.class.getName());
}
